#pragma once
#include "Stdafx.h"

namespace Pulpy
{
	template <class T>
	class Vector3D
	{
	private:
		T X;
		T Y;
		T Z;
	public:
		Vector3D(const Vector3D<T> &v): X(v.X), Y(v.Y), Z(v.Z) { }
		Vector3D(T xin,T yin,T zin): X(xin), Y(yin), Z(zin) { }
		Vector3D():X(0),Y(0),Z(0) { }
		~Vector3D() { X = 0; Y = 0; Z = 0; }

		float getMag() { return sqrt(X*X+Y*Y+Z*Z); }
		T getX() { return X; }
		T getY() { return Y; }
		T getZ() { return Z; }
		Vector3D<T> normalize() { return (this)/getMag(); }

		Vector3D<T> operator* (float mul) {	Vector3D<T> result = *this; result *= mul; return result; } 
		Vector3D<T> operator+ (const Vector3D<T> &v) { Vector3D<T> result = *this; result += v; return result; }
		Vector3D<T> operator- (const Vector3D<T> &v) { Vector3D<T> result = *this; result -= v; return result; }
		Vector3D<T> operator/ (float div) { Vector3D<T> result = *this; result /= div; return result; }
		Vector3D<T> operator*= (float mul) { X *= mul; Y *= mul; Z *= mul; return *this; } 
		Vector3D<T> operator+= (const Vector3D<T> &v) { X += v.X; Y += v.Y; Z += v.Z; return *this; }
		Vector3D<T> operator-= (const Vector3D<T> &v) { X -= v.X; Y -= v.Y; Z -= v.Z; return *this; }
		bool operator ==(const Vector3D<T> &v) { return X == v.X && Y == v.Y && Z == v.Z; }
		Vector3D<T> operator/= (float div) {
			try
			{
				if(div == 0)
					throw 0;
				X /= div;
				Y /= div;
				Z /= div;
				return *this;
			}
			catch(int)
			{
				Logger::getInstance().addLog("Division By 0");
				return *this;
			}
		}
		Vector3D<T> operator^ (const Vector3D<T> &v) { return Vector3D<T>((Y * v.Z - v.Y * Z), -(X * v.Z - v.X * Z), (X * v.Y - v.X * Y)); }
		float operator* (const Vector3D<T> &v) { return X * v.X + Y * v.Y + z * v.Z; }

		friend std::ostream& operator<<(std::ostream &out, const Vector3D<T> &v)
		{
			out << "("  << "," << v.Y << "," << v.Z << ")" << std::endl;
			return out;
		}
	};
}